﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Timers;

namespace Monitor
{
    
    /// <summary>
    /// Interaction logic for _2DChart.xaml
    /// </summary>
    /// 
    

    public partial class _2DChart : UserControl
    {

        

        TextBox ChartName;
        TextBox YaxisName;
        TextBox XaxisName;
        Rectangle ChartBoundry;
  
        int SampleNum = 200;
        int ChartScaleX = 10;
        List<Line> xLines;
        Polyline waveform;

        int ScaleYNum = 10;
        double MinY = -2;
        double MaxY = 2;
        List<Line> yLines;

        List<double> points;

        public double max(double a, double b)
        {  
            return a > b ? a : b;
        }

        public _2DChart()
        {   
            InitializeComponent();
            Initial_ChartName();
            Initial_ChartBoundry();
            Initial_YaxisName();
            Initial_XaxisName();
            Initial_xLine();
            Initial_yLine();
        }


        public void InsertNode(double value)
        {
            //
            double x,y;
            points.Add(value);

            //
            if(points.Count>SampleNum)
            {
                points.RemoveAt(0);
            }

            //
            waveform.Points.Clear();
            for(int i = 0;i<points.Count;i++)
            {
                
                //
                x = max((FrameCanvas.ActualWidth / 16), 80) + ChartBoundry.Width - (ChartBoundry.Width / xLines.Count) * (points.Count - i);
                y = FrameCanvas.ActualHeight - (((points[i]-MinY) / (MaxY - MinY))*ChartBoundry.Height + max((FrameCanvas.ActualHeight / 16), 80));
                waveform.Points.Add(new Point(x, y));   
       
            }

        }

        private void Initial_xLine()
        {
            xLines = new List<Line>();
            points = new List<double>();
            waveform = new Polyline();
            waveform.Points = new PointCollection();

            waveform.Stroke = System.Windows.Media.Brushes.GreenYellow;
            waveform.StrokeThickness = 2;
           
            FrameCanvas.Children.Add(waveform);

            for (int i = 0; i < SampleNum; i++)
            {
                Line  newLine = new Line();
                newLine.Stroke = System.Windows.Media.Brushes.White;
                newLine.StrokeThickness = 0.8;
                newLine.StrokeDashArray = new DoubleCollection() { 2 };        
                xLines.Add(newLine); 
                FrameCanvas.Children.Add(newLine);               
            }    

            //


        }

        private void Initial_yLine()
        {
            yLines = new List<Line>();
          
            for (int i = 1; i < ScaleYNum; i++)
            {
                
                Line newLine = new Line();

                newLine.Stroke = System.Windows.Media.Brushes.White;
                newLine.StrokeThickness = 0.8;
                
                newLine.StrokeDashArray = new DoubleCollection() { 2 };
                yLines.Add(newLine);
                FrameCanvas.Children.Add(newLine);

            }
        }



        private void Initial_ChartName()
        {
            
            ChartName = new TextBox();
            ChartName.Text = "ChartName";
            ChartName.Background = FrameCanvas.Background;
            ChartName.FontSize = 32;
            ChartName.Foreground = System.Windows.Media.Brushes.Red;
            ChartName.BorderThickness = new Thickness(0);
            ChartName.IsReadOnly = true;
            FrameCanvas.Children.Add(ChartName);
    
        }

        public void SetChartName(string name)
        {
            if(ChartName.Text != name)
            {
                ChartName.Text = name;
            }    
        }

        public void Initial_ChartBoundry()
        {
            ChartBoundry = new Rectangle();
            ChartBoundry.Stroke = System.Windows.Media.Brushes.White;
            ChartBoundry.StrokeThickness = 1;
            FrameCanvas.Children.Add(ChartBoundry);
            
        }

        private void Initial_YaxisName()
        {

            YaxisName = new TextBox();
            YaxisName.Text = "YaxisName";
            YaxisName.Background = FrameCanvas.Background;
            YaxisName.FontSize = 20;
            YaxisName.Foreground = System.Windows.Media.Brushes.Red;
            YaxisName.BorderThickness = new Thickness(0);
            YaxisName.IsReadOnly = true;
            YaxisName.LayoutTransform = new RotateTransform(270);
            FrameCanvas.Children.Add(YaxisName);
        }


        public void SetYAxisName(string name)
        {
            if (YaxisName.Text != name)
            {
                YaxisName.Text = name;
            } 
        }

        private void Initial_XaxisName()
        {
            XaxisName = new TextBox();
            XaxisName.Text = "XaxisName";
            XaxisName.Background = FrameCanvas.Background;
            XaxisName.FontSize = 20;
            XaxisName.Foreground = System.Windows.Media.Brushes.Red;
            XaxisName.BorderThickness = new Thickness(0);
            XaxisName.IsReadOnly = true;
            FrameCanvas.Children.Add(XaxisName);

        }

        public void SetXAxisName(string name)
        {
            
            if (XaxisName.Text != name)
            {
                XaxisName.Text = name;
            } 

        }

        private void FrameCanvas_SizeChanged(object sender, SizeChangedEventArgs e)
        {

            Canvas.SetLeft(ChartBoundry, max((FrameCanvas.ActualWidth / 16), 80));
            Canvas.SetBottom(ChartBoundry, max((FrameCanvas.ActualHeight / 16), 80));
            ChartBoundry.Width = FrameCanvas.ActualWidth - max((FrameCanvas.ActualWidth / 16), 80) * 2;
            ChartBoundry.Height = FrameCanvas.ActualHeight - max((FrameCanvas.ActualHeight / 16), 80) * 2;

            Canvas.SetLeft(ChartName, (FrameCanvas.ActualWidth - ChartName.Text.Length * ChartName.FontSize * 0.5) * 0.5);
            Canvas.SetBottom(ChartName, max((FrameCanvas.ActualHeight / 16), 80) + FrameCanvas.ActualHeight - max((FrameCanvas.ActualHeight / 16), 80) * 2 + 5);

            Canvas.SetLeft(YaxisName, max((FrameCanvas.ActualWidth / 16), 80) - YaxisName.FontSize - 60);
            Canvas.SetBottom(YaxisName, (FrameCanvas.ActualHeight - YaxisName.Text.Length * YaxisName.FontSize * 0.5) * 0.5);

            Canvas.SetBottom(XaxisName, max((FrameCanvas.ActualHeight / 16), 80) - XaxisName.FontSize - 40);
            Canvas.SetLeft(XaxisName, (FrameCanvas.ActualWidth - XaxisName.Text.Length * ChartName.FontSize * 0.5) * 0.5);
            for (int i = 0; i < ChartScaleX; i++)
            {
                //
                xLines[i].X1 = max((FrameCanvas.ActualWidth / 16), 80) + ChartBoundry.Width - (ChartBoundry.Width / ChartScaleX) * (i + 1);
                xLines[i].X2 = xLines[i].X1;
                xLines[i].Y1 = max((FrameCanvas.ActualHeight / 16), 80);
                xLines[i].Y2 = xLines[i].Y1 + ChartBoundry.Height;
            }

            for (int i = 0; i < yLines.Count; i++)
            {
                yLines[i].X1 = max((FrameCanvas.ActualWidth / 16), 80);
                yLines[i].X2 = yLines[i].X1 + ChartBoundry.Width;
                yLines[i].Y1 = FrameCanvas.ActualHeight - (max((FrameCanvas.ActualHeight / 16), 80) + ((i + 1) * ChartBoundry.Height / ScaleYNum));
                yLines[i].Y2 = yLines[i].Y1;

            }

        }

       
            
        

    }

}
